﻿using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Security;
using SHZY.Common.Enum;
using SHZY.Common.Extension;
using SHZY.Common.Filter;
using SHZY.Common.Models;
using SHZY.Common.Security;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Entitys.Permission;
using SHZY.Systems.Entitys.System;
using SHZY.Systems.Interfaces.System;
using SHZY.Business.Entitys;
using SHZY.Business.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Newtonsoft.Json.Linq;
using SHZY.Business.Entitys.Entity;
using SHZY.BaseData.Entitys;
using Google.Protobuf;
using SHZY.TaskScheduler;
using System;
using SHZY.BaseData.Entitys.Dto.QmsBaseDefect;
using SHZY.Common.FR;
using StackExchange.Profiling.Internal;
using System.Linq;
using NPOI.SS.Formula.Functions;
using Aspose.Cells;
using SHZY.BaseData.Interfaces;
using SHZY.Business.Entitys.Dto.QmsBusiIpqcinspectionlot;
using SHZY.BaseData.Entitys.Entity;
using SHZY.Business.Entitys.Dto.QmsBusiInspectionlot;

namespace SHZY.Business;

/// <summary>
/// 业务实现：检验批.
/// </summary>
[ApiDescriptionSettings(Tag = "Business", Name = "IpqcInspectionlot", Order = 200)]
[Route("api/Business/[controller]")]
public class QmsBusiIpqcinspectionlotService : IQmsBusiIpqcinspectionlotService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<QmsBusiIpqcinspectionlotEntity> _repository;

    /// <summary>
    /// 数据接口服务.
    /// </summary>
    private readonly IDataInterfaceService _dataInterfaceService;

    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager _userManager;

    private readonly ITenant _db;
    /// <summary>
    /// 单据编号服务
    /// </summary>
    private readonly IBillRullService _billRullService;

    /// <summary>
    /// 检验批项目服务
    /// </summary>
    private readonly IQmsBusiIpqcinspectionitemService _iqmsBusiIpqcinspectionitemService;

    /// <summary>
    /// 数据字典服务.
    /// </summary>
    private readonly IDictionaryDataService _dictionaryDataService;

    /// <summary>
    /// 初始化一个<see cref="QmsBusiIpqcinspectionlotService"/>类型的新实例.
    /// </summary>
    public QmsBusiIpqcinspectionlotService(
        ISqlSugarRepository<QmsBusiIpqcinspectionlotEntity> qmsBusiIpqcinspectionlotRepository,
        IDataInterfaceService dataInterfaceService,
        ISqlSugarClient context,
        IUserManager userManager,
        IDictionaryDataService dictionaryDataService,
        IQmsBusiIpqcinspectionitemService iqmsBusiIpqcinspectionitemService,
        IBillRullService billRullService
        )
    {
        _repository = qmsBusiIpqcinspectionlotRepository;
        _dataInterfaceService = dataInterfaceService;
        _userManager = userManager;
        _iqmsBusiIpqcinspectionitemService = iqmsBusiIpqcinspectionitemService;
        _dictionaryDataService = dictionaryDataService;
        _db = context.AsTenant();
        _billRullService = billRullService;

    }

    /// <summary>
    /// 获取检验批.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {
        var data = await _repository.FirstOrDefaultAsync(x => x.Id == id);
        var entity = data.Adapt<QmsBusiIpqcinspectionlotInfoOutput>();
        entity.materialDes = "";
        var materialInfo = await _repository.Context.Queryable<QmsBaseMaterialEntity>().Where(x => x.Code == entity.materialCode && x.DeleteMark == null).FirstAsync();
        if (materialInfo != null)
        {
            entity.materialDes = materialInfo.Name;
        }

        entity.employeeId = "";
        var userInfo = await _repository.Context.Queryable<UserEntity>().Where(x => x.Account == entity.employeeCode && x.DeleteMark == null).FirstAsync();
        if (userInfo != null)
        {
            entity.employeeId = userInfo.Id;
        }

        var factoryList = await _repository.Context.Queryable<QmsBaseFactorystructureEntity>().Where(x => x.DeleteMark == null).ToListAsync();
        var stationList = await _repository.Context.Queryable<QmsBaseStationEntity>().Where(x => x.DeleteMark == null).ToListAsync();

        entity.workshopId = factoryList.Find(x => x.Id.Equals(entity.workshopId))?.FullName;
        entity.teamId = factoryList.Find(x => x.Id.Equals(entity.teamId))?.FullName;
        entity.workshopSectionId = factoryList.Find(x => x.Id.Equals(entity.workshopSectionId))?.FullName;
        entity.stationId = stationList.Find(x => x.Id.Equals(entity.stationId))?.FullName;

        if (!string.IsNullOrEmpty(entity.processIdList))
        {
            string[] processIdList = entity.processIdList.Split(',');
            var processNameList = await _repository.Context.Queryable<QmsBaseArtroutedetailEntity>().Where(x => processIdList.Contains(x.Id) && x.DeleteMark == null).Select(x => x.FullName).ToListAsync();
            entity.processIdList = string.Join(",", processNameList);
        }
        return entity;
    }

    /// <summary>
    /// 获取检验批列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("")]
    public async Task<dynamic> GetList([FromQuery] QmsBusiIpqcinspectionlotListQueryInput input)
    {
        var queryable = _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity, QmsBaseMaterialEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.MaterialCode == b.Code && b.DeleteMark == null))
            .WhereIF(!string.IsNullOrEmpty(input.code), a => a.Code.Contains(input.code))
            .Where(a => a.DeleteMark == null)
            .WhereIF(input.status != null, a => a.Status == input.status)
            .WhereIF(!string.IsNullOrEmpty(input.statusType) && input.statusType == "Wait", a => a.Status == 0 || a.Status == 1)
            .WhereIF(!string.IsNullOrEmpty(input.judgeStatus), a => a.JudgeStatus == input.judgeStatus)
            .WhereIF(!string.IsNullOrEmpty(input.type), a => a.Type.Contains(input.type))
            .WhereIF(!string.IsNullOrEmpty(input.material), (a, b) => b.Code.Contains(input.material) || b.Type.Contains(input.material))
            .WhereIF(!string.IsNullOrEmpty(input.orderNo), (a, b) => a.OrderNo.Contains(input.orderNo))
            .WhereIF(!string.IsNullOrEmpty(input.employeeCode), (a, b) => a.EmployeeCode.Contains(input.employeeCode) || a.EmployeeName.Contains(input.employeeCode))
            .Select((a, b) => new QmsBusiIpqcinspectionlotListOutput
            {
                id = a.Id,
                code = a.Code,
                inspectionCode = a.InspectionCode,
                date = a.Date,
                type = a.Type,
                inspectType = a.InspectType,
                workshopId = a.WorkshopId,
                teamId = a.TeamId,
                workshopSectionId = a.WorkshopSectionId,
                stationId = a.StationId,
                processIdList = a.ProcessIdList,
                materialCode = a.MaterialCode,
                materialDes = SqlFunc.IsNull(b.Name, ""),
                productionQty = a.ProductionQty,
                employeeCode = a.EmployeeCode,
                employeeName = a.EmployeeName,
                orderNo = a.OrderNo,
                remark = a.Remark,
                status = a.Status,
                closeDes = a.CloseDes,
                closeDate = a.CloseDate,
                judgeStatus = a.JudgeStatus,
                udNo = a.UdNo,
                decision = a.Decision,
                decisionName = a.DecisionName,
                destructivenessQty = a.DestructivenessQty,
                receiveQty = a.ReceiveQty,
                decisionDesc = a.DecisionDesc,
                overdue = a.Overdue,
                enabledMark = a.EnabledMark,
                startTime = a.StartTime,
                endTime = a.EndTime,
                creatorTime = a.CreatorTime
            }).MergeTable();
            //.OrderByIF(string.IsNullOrEmpty(input.sidx), " a.F_StartTime desc,a.F_CreatorTime asc");
        if (!string.IsNullOrEmpty(input.sidx))
        {
            queryable.OrderBy(input.sidx + " " + input.sort);
        }
        else
        {
            queryable.OrderByDescending(it => it.startTime).OrderBy(it => it.creatorTime);
            //queryable.OrderBy("a.startTime desc,a.creatorTime asc");
        }

        var data = await queryable.ToPagedListAsync(input.currentPage, input.pageSize);

        if (data.list.Count() > 0)
        {
            var factoryList = await _repository.Context.Queryable<QmsBaseFactorystructureEntity>().Where(x => x.DeleteMark == null).ToListAsync();
            var stationList = await _repository.Context.Queryable<QmsBaseStationEntity>().Where(x => x.DeleteMark == null).ToListAsync();

            foreach (var item in data.list)
            {
                item.workshopId = factoryList.Find(x => x.Id.Equals(item.workshopId))?.FullName;
                item.teamId = factoryList.Find(x => x.Id.Equals(item.teamId))?.FullName;
                item.workshopSectionId = factoryList.Find(x => x.Id.Equals(item.workshopSectionId))?.FullName;
                item.stationId = stationList.Find(x => x.Id.Equals(item.stationId))?.FullName;
                if (!string.IsNullOrEmpty(item.processIdList))
                {
                    string[] processIdList = item.processIdList.Split(',');
                    var processNameList = await _repository.Context.Queryable<QmsBaseArtroutedetailEntity>().Where(x => processIdList.Contains(x.Id) && x.DeleteMark == null).Select(x => x.FullName).ToListAsync();
                    item.processIdList = string.Join(",", processNameList);
                }

            }
        }

        return PageResult<QmsBusiIpqcinspectionlotListOutput>.SqlSugarPageResult(data);
    }

    /// <summary>
    /// 保存检验数据.
    /// </summary>
    /// <param name="data">参数.</param>
    /// <returns></returns>
    [HttpPut("")]
    public async Task Save([FromBody] JObject _data)
    {
        string id = _data["id"].ToString();
        string code = _data["code"].ToString();
        string remark = _data["remark"].ToString();
        // app端检验项目是单独保存接口，pc端保存提交时才执行以下方法
        if (_userManager.UserOrigin.Equals("pc"))
        {

            // 校验是否有检验条目抽样数量是0，如果是0，则需要输入抽样数量
            if (await _repository.Context.Queryable<QmsBusiIpqcinspectionitemEntity>().Where(x => x.Code == code && x.SamplingQty == 0 && x.DeleteMark == null && x.EnabledMark == 1).CountAsync() > 0)
            {
                throw Oops.Oh("存在检验条目未确认抽样数量，请确认");
            }

            // 保存检验项目数据
            if (!(await _iqmsBusiIpqcinspectionitemService.Save(code, _data)))
            {
                throw Oops.Oh("保存检验项目数据异常");
            }
        }

        // 保存检验批信息
        QmsBusiIpqcinspectionlotEntity qmsBusiIpqcinspectionlotEntity = new QmsBusiIpqcinspectionlotEntity();
        qmsBusiIpqcinspectionlotEntity.Id = id;
        qmsBusiIpqcinspectionlotEntity.Status = 1;
        qmsBusiIpqcinspectionlotEntity.Remark = remark;
        // 保存时，如果当前是未检验状态，则记录开始检验时间
        if (await _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity>().Where(x => x.Id == id && x.Status == 0).CountAsync() > 0)
        {
            qmsBusiIpqcinspectionlotEntity.Date = DateTime.Now;
            qmsBusiIpqcinspectionlotEntity.StartTime = DateTime.Now;
        }

        var isOk = await _repository.Context.Updateable(qmsBusiIpqcinspectionlotEntity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
        if (!isOk)
            throw Oops.Oh(ErrorCode.COM1001);
    }

    /// <summary>
    /// 提交检验数据.
    /// </summary>
    /// <param name="data">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task<dynamic> Submit([FromBody] JObject _data)
    {
        string id = _data["id"].ToString();
        string code = _data["code"].ToString();
        string remark = _data["remark"].ToString();
       
        string materialCode = _data["materialCode"].ToString();
        string inspectType = _data["inspectType"].ToString();
        int status = 2;
        string confirmed = _data["confirmed"].ToString();// 二次确认标识

        // 校验是否有检验条目抽样数量是0，如果是0，则需要输入抽样数量
        if (await _repository.Context.Queryable<QmsBusiIpqcinspectionitemEntity>().Where(x => x.Code == code && x.SamplingQty == 0 && x.DeleteMark == null && x.EnabledMark == 1).CountAsync() > 0)
        {
            throw Oops.Oh("存在检验条目未确认抽样数量，请确认");
        }

        // app端检验项目是单独保存接口，pc端保存提交时才执行以下方法
        if (_userManager.UserOrigin.Equals("pc"))
        {
            // 保存检验项目数据
            if (!(await _iqmsBusiIpqcinspectionitemService.Save(code, _data)))
            {
                throw Oops.Oh("保存检验项目数据异常");
            }
        }
        // 提交检验批时校验是否开启了SN号管理
        var materialInfo = await _repository.Context.Queryable<QmsBaseMaterialEntity>().Where(x => x.Code == materialCode && x.DeleteMark == null && x.EnabledMark == 1).FirstAsync();
        if (materialInfo.IsSn.Equals("Y"))
        {
            // 如果序号与标题一致，或者标题为空，则提示检验项目需要填写具体的SN号
            int count = await _repository.Context.Queryable<QmsBusiIpqcinspectionitemdataEntity>().Where(x => x.Code == code && x.DeleteMark == null && x.EnabledMark == 1 && string.IsNullOrEmpty(x.Serial)).CountAsync();
            if (count > 0)
            {
                throw Oops.Oh("物料开启了SN号管理，检验项目需要填写具体的SN号");
            }
        }

        // 校验需要输入破坏性数量的检验条目是否没有输入
        if (await _repository.Context.Queryable<QmsBusiIpqcinspectionitemEntity>().Where(x => x.Code == code && x.Destructiveness == "Y" && x.DestructivenessQty== 0 && x.DeleteMark == null && x.EnabledMark == 1).CountAsync() > 0)
        {
            throw Oops.Oh("存在检验条目未输入破坏性数量，请确认");
        }


        // 校验检验项目是否完成检验结果的输入
        if (await _repository.Context.Queryable<QmsBusiIpqcinspectionitemdataEntity>().Where(x => x.Code == code && string.IsNullOrEmpty(x.Status) && x.DeleteMark == null && x.EnabledMark == 1).CountAsync() > 0)
        {
            throw Oops.Oh("存在检验项目未输入检验结果，请确认");
        }

        // 如果有检验项目是NG，则标识检验批NG，排除有参考标识的检验项目
        string judgeStatus = "OK";
        if (await _repository.Context.Queryable<QmsBusiIpqcinspectionitemEntity>().Where(x => x.Code == code && x.Status == "NG" && x.ReferTo != "Y" && x.DeleteMark == null && x.EnabledMark == 1).CountAsync() > 0)
        {
            judgeStatus = "NG";
        }

        string decision = "";
        string decisionName = "";
        // 提交检验批时，统计破坏性数量
        // 1.合格并且没有破坏性数量，则默认使用合格，接收决策，并标识状态已过账
        // 2.合格并且有破坏性数量，则需要用户二次确认，二次确认后标识状态已过账
        // 3.不合格直接生成不合格品评审单
        // 统计破坏性数量
        int destructivenessQty = (await _repository.Context.Queryable<QmsBusiIpqcinspectionitemEntity>().GroupBy(x => new { x.Code }).Where(x => x.Code == code && x.Destructiveness == "Y" && x.DeleteMark == null && x.EnabledMark == 1).Select(x => new
        {
            total = SqlFunc.AggregateSum(x.DestructivenessQty)
        }).FirstAsync())?.total ?? 0;
        // 合格
        if (judgeStatus.Equals("OK"))
        {
            // 1.合格没有破坏性数量，则默认使用合格，接收决策，并标识状态已过账
            // 2.合格并且有破坏性数量，则需要用户二次确认，二次确认后标识状态已过账
            if (destructivenessQty == 0 || confirmed.Equals("Y"))
            {
                decision = "101";
                decisionName = "合格，接收";
                status = 3;
            }
            else
            {
                return new { confirm = "Y" };
            }
        }

        // 填充检验批信息
        QmsBusiIpqcinspectionlotEntity qmsBusiIpqcinspectionlotEntity = new QmsBusiIpqcinspectionlotEntity();
        qmsBusiIpqcinspectionlotEntity.Id = id;
        qmsBusiIpqcinspectionlotEntity.Decision = decision;
        qmsBusiIpqcinspectionlotEntity.DecisionName = decisionName;
        qmsBusiIpqcinspectionlotEntity.JudgeStatus = judgeStatus;
        qmsBusiIpqcinspectionlotEntity.Status = status;
        qmsBusiIpqcinspectionlotEntity.Remark = remark;
        qmsBusiIpqcinspectionlotEntity.EndTime = DateTime.Now;
        qmsBusiIpqcinspectionlotEntity.DestructivenessQty = destructivenessQty;

        // 保存时，如果当前是未检验状态，则记录开始检验时间
        if (await _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity>().Where(x => x.Id == id && x.Status == 0).CountAsync() > 0)
        {
            qmsBusiIpqcinspectionlotEntity.Date = DateTime.Now;
            qmsBusiIpqcinspectionlotEntity.StartTime = DateTime.Now;
        }
        try
        {
            // 开启事务
            _repository.Context.BeginTran();
            // 保存检验批信息
            var isOk = await _repository.Context.Updateable(qmsBusiIpqcinspectionlotEntity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
            if (!isOk)
                throw Oops.Oh(ErrorCode.COM1001);

            // 检验批为NG时，生成不合格品处理单
            if (judgeStatus.Equals("NG"))
            {
                await DefectHandle(code);
            }

            // 提交事务
            _repository.Context.CommitTran();
            return new { confirm = "" };
        }
        catch (Exception ex)
        {
            // 回滚事务
            _repository.Context.RollbackTran();
            throw Oops.Oh(ex.Message);
        }
    }

    /// <summary>
    /// 不合格品处理单.
    /// </summary>
    /// <param name="code">检验批号.</param>
    /// <returns></returns>
    [NonAction]
    public async Task DefectHandle(string code)
    {
        List<QmsBusiDefecthandleEntity> defecthandleList = new List<QmsBusiDefecthandleEntity>();
        List<QmsBusiDefecthandledetailEntity> defecthandledetailList = new List<QmsBusiDefecthandledetailEntity>();
        var ipqcInspectionItemList = await _repository.Context.Queryable<QmsBusiIpqcinspectionitemEntity>().Where(x => x.Code == code && x.Status == "NG" && x.ReferTo != "Y" && x.DeleteMark == null && x.EnabledMark == 1).OrderBy(x => x.CreatorTime, OrderByType.Asc).ToListAsync();

        // 获取处理单号
        string defectHandleCode = await _billRullService.GetBillNumber("DefectHandle");

        foreach (var ipqcInspectionItem in ipqcInspectionItemList)
        {
            // 不良数量
            int defectQty = await _repository.Context.Queryable<QmsBusiIpqcinspectionitemdataEntity>().Where(x => x.InspectionItem == ipqcInspectionItem.Id && x.Status == "NG" && x.DeleteMark == null && x.EnabledMark == 1).CountAsync();

            QmsBusiDefecthandledetailEntity defecthandledetailEntity = new QmsBusiDefecthandledetailEntity();
            defecthandledetailEntity.DefectHandleCode = defectHandleCode;
            defecthandledetailEntity.InspectionItemId = ipqcInspectionItem.Id;
            defecthandledetailEntity.InnspectionCode = ipqcInspectionItem.InnspectionCode;
            defecthandledetailEntity.InnspectionName = ipqcInspectionItem.InnspectionName;
            defecthandledetailEntity.InnspectionEntry = ipqcInspectionItem.InnspectionEntry;
            defecthandledetailEntity.InnspectionEntryName = ipqcInspectionItem.InnspectionEntryName;
            int samplingQty = ipqcInspectionItem.SamplingQty ?? 0;
            defecthandledetailEntity.SamplingQty = samplingQty;
            decimal defectRate = ((decimal)defectQty / (decimal)samplingQty) * 100;
            defectRate = decimal.Round(defectRate, 2);
            defecthandledetailEntity.DefectQty = defectQty;
            defecthandledetailEntity.DefectRate = defectRate;
            defecthandledetailList.Add(defecthandledetailEntity);
        }

        // 如果存在缺陷记录，则需要创建不合格品处理单
        if (defecthandledetailList.Count > 0)
        {
            // 查询检验批信息
            var ipqcInspectionlotEntity = await _repository.Context.Queryable<QmsBusiIpqcinspectionlotEntity>().Where(x => x.Code == code && x.DeleteMark == null && x.EnabledMark == 1).FirstAsync();

            // 查询物料信息
            var materialEntity = await _repository.Context.Queryable<QmsBaseMaterialEntity>().Where(x => x.Code == ipqcInspectionlotEntity.MaterialCode && x.DeleteMark == null && x.EnabledMark == 1).FirstAsync();

           
            QmsBusiDefecthandleEntity defecthandleEntity = new QmsBusiDefecthandleEntity();
            defecthandleEntity.Type = ipqcInspectionlotEntity.Type;
            defecthandleEntity.Code = defectHandleCode;
            defecthandleEntity.Status = 0;
            defecthandleEntity.InspectionLotId = ipqcInspectionlotEntity.Id;
            defecthandleEntity.InspectionLot = ipqcInspectionlotEntity.Code;
            defecthandleEntity.BatchNumber = "";
            defecthandleEntity.MaterialCode = ipqcInspectionlotEntity.MaterialCode;
            defecthandleEntity.MaterialDes = materialEntity?.Name;
            defecthandleEntity.Supplier = "";
            defecthandleEntity.SupplierDes = "";
            defecthandleEntity.IncomingQty = 0;
            defecthandleEntity.OrderNo = ipqcInspectionlotEntity.OrderNo;
            defecthandleEntity.ProductionQty = ipqcInspectionlotEntity.ProductionQty;
            defecthandleEntity.Problem = "";
            defecthandleEntity.Decision = "";
            defecthandleEntity.DecisionName = "";
            defecthandleEntity.Remark = "";
            defecthandleList.Add(defecthandleEntity);
        }

        // 新增不合格品处理单
        if (defecthandleList.Count > 0)
        {
            var isOk1 = await _repository.Context.Insertable(defecthandleList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
            if (isOk1 < 1)
                throw Oops.Oh(ErrorCode.COM1000);

            var isOk2 = await _repository.Context.Insertable(defecthandledetailList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
            if (isOk2 < 1)
                throw Oops.Oh(ErrorCode.COM1000);
        }
    }


    /// <summary>
    /// 关闭检验批.
    /// </summary>
    /// <returns></returns>
    [HttpPost("close")]
    public async Task InspectionlotClose([FromBody] QmsBusiIpqcinspectionlotUpInput input)
    {
        var isOk = await _repository.Context.Updateable<QmsBusiIpqcinspectionlotEntity>().SetColumns(it => new QmsBusiIpqcinspectionlotEntity()
        {
            Status = 4,
            CloseDate = DateTime.Now,
            CloseDes = input.closeDes,
            LastModifyTime = DateTime.Now,
            LastModifyUserId = _userManager.UserId
        }).Where(x => x.Id == input.id && (x.Status == 0 || x.Status == 1)).ExecuteCommandHasChangeAsync();

    }

    #region


    /// <summary>
    /// fastReport
    /// </summary>
    /// <param name="id">主键值. 0 不合格 1合格</param>
    /// <returns></returns>
    [HttpGet("fastreportIpqcInspectionlot/{id}")]
    public async Task<dynamic> fastreportIpqcInspectionlot(string id)
    {
        FileResult ms = null;
        var result = await _repository.FirstOrDefaultAsync(x => x.Id == id);
        //var ob = result.Adapt<QmsBusiInspectionlotInfoOutput>();

        // fr数据源
        Dictionary<string, List<object>> dicList = new Dictionary<string, List<object>>();

        // 检验批项目表
        var qt = await _repository.Context.Queryable<QmsBusiIpqcinspectionitemEntity>().Where(a => result.Code.Contains(a.Code))
            .Where(a => a.ReferTo.Equals("N") && a.EnabledMark == 1 && a.DeleteMark == null)
            .ToListAsync();

        if (qt != null && qt.Count > 0)
        {
            // 获取检查水平字典项
            var iType = await _dictionaryDataService.GetList("InspectionType");

            List<object> qtlist = new List<object>();
            var qtarrId = qt.Select(i => i.Id).ToArray();

            // 检验批项目结果
            var qd = await _repository.Context.Queryable<QmsBusiIpqcinspectionitemdataEntity>()
                .Where(a => a.Id == id && a.EnabledMark == 1 && a.DeleteMark == null && qtarrId.Contains(a.InspectionItem)).ToListAsync();
            foreach (var item in qt)
            {
                var iTypeObj = iType
                  .Find(d => d.EnCode.Equals(item.Type));

                qtlist.Add(new
                {
                    SamplingTypeDes = item.SamplingTypeDes,
                    InnspectionEntry = item.InnspectionEntryName,
                    InnspectionMethod = item.InnspectionMethodName,
                    Type = iTypeObj?.FullName,
                    SamplingQty = item.SamplingQty,
                    Status = item.Status,
                    Sum = qd.Where(a => a.InspectionItem == item.Id).Count(),
                });
            }
            dicList.Add("QmsBusiInspectionitemdataEntityRef", qtlist);
        }

        // 报检单表
        var qb = await _repository.Context.Queryable<QmsBusiIpqcinspectionEntity>().Where(a => result.Code.Contains(a.Code) && a.EnabledMark == 1 && a.DeleteMark == null).ToListAsync();

        if (qb != null && qb.Count > 0)
        {
            List<object> qblist = new List<object>();
            foreach (var item in qb)
            {
                qblist.Add(new
                {
                    Code = item.Code,
                    OrderNo = item.OrderNo,
                    ProductionQty = item.ProductionQty,
                });
            }
            dicList.Add("QmsBusiInspectionEntityRef", qblist);
        }

        Dictionary<string, string> dic = new Dictionary<string, string>();
        dic.Add("MaterialCode", result.MaterialCode);
        dic.Add("Supplier", "");
        dic.Add("EmployeeName", result.EmployeeName);
        dic.Add("StartTime", result.StartTime.ToString());
        dic.Add("EndTime", result.EndTime.ToString());
        dic.Add("IncomingQty", result.ProductionQty.ToString());
        dic.Add("Remark", result.Remark);

        if (result?.UdNo == 1)
        {
            // 输出合格fr
            ms = CreateFR.ExportFastReportPDF(dicList, dic, "Qualified.frx", "", "");
        }
        else
        {
            var qtIdArr = qt.Select(s => s.Id).ToArray();
            // 缺陷记录表
            var qf = await _repository.Context.Queryable<QmsBusiIpqcinspectionitemdefectEntity>()
                .Where(a => a.EnabledMark == 1 && a.DeleteMark == null && qtIdArr.Contains(a.InspectionItem)).ToListAsync();

            if (qf != null && qf.Count > 0)
            {
                // 获取检查水平字典项
                var iType = await _dictionaryDataService.GetList("severity");

                List<object> qflist = new List<object>();
                foreach (var item in qf)
                {
                    var iTypeObj = iType.Find(d => d.EnCode.Equals(item.Severity));

                    qflist.Add(new
                    {
                        Number = item.Number,
                        DefectName = item.DefectName,
                        DefectQty = item.DefectQty,
                        Severity = iTypeObj?.FullName,
                    });
                }

                dicList.Add("QmsBusiInspectionitemdefectEntityRef", qflist);
            }

            // 输出不合格fr
            ms = CreateFR.ExportFastReportPDF(dicList, dic, "UnQualified.frx", "", "");
        }

        return ms;
    }

    #endregion
}